package android.os.mock.storage;

import android.os.Parcel;
import android.os.Parcelable;
import android.os.StatFs;
import android.system.StructStatVfs;
import android.util.Log;

/**
 * @hide
 * Mock at {@link StatFs}
 */
public class MockStructStatVfs implements Parcelable {
    /** File system block size (used for block counts). */
    public long f_bsize; /*unsigned long*/

    /** Fundamental file system block size. */
    public long f_frsize; /*unsigned long*/

    /** Total block count. */
    public long f_blocks; /*fsblkcnt_t*/

    /** Free block count. */
    public long f_bfree; /*fsblkcnt_t*/

    /** Free block count available to non-root. */
    public long f_bavail; /*fsblkcnt_t*/

    /** Total file (inode) count. */
    public long f_files; /*fsfilcnt_t*/

    /** Free file (inode) count. */
    public long f_ffree; /*fsfilcnt_t*/

    /** Free file (inode) count available to non-root. */
    public long f_favail; /*fsfilcnt_t*/

    /** File system id. */
    public long f_fsid; /*unsigned long*/

    /** Bit mask of ST_* flags. */
    public long f_flag; /*unsigned long*/

    /** Maximum filename length. */
    public long f_namemax; /*unsigned long*/

    public String path;

    public MockStructStatVfs() {}

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(f_bsize);
        dest.writeLong(f_frsize);
        dest.writeLong(f_blocks);
        dest.writeLong(f_bfree);
        dest.writeLong(f_bavail);
        dest.writeLong(f_files);
        dest.writeLong(f_ffree);
        dest.writeLong(f_favail);
        dest.writeLong(f_fsid);
        dest.writeLong(f_flag);
        dest.writeLong(f_namemax);

        dest.writeString(path);
    }

    public void readFromParcel(Parcel source) {
        f_bsize = source.readLong();
        f_frsize = source.readLong();
        f_blocks = source.readLong();
        f_bfree = source.readLong();
        f_bavail = source.readLong();
        f_files = source.readLong();
        f_ffree = source.readLong();
        f_favail = source.readLong();
        f_fsid = source.readLong();
        f_flag = source.readLong();
        f_namemax = source.readLong();

        path = source.readString();
    }

    public static final @android.annotation.NonNull Creator<MockStructStatVfs> CREATOR
            = new Creator<MockStructStatVfs>() {
        public MockStructStatVfs createFromParcel(Parcel source) {
            return new MockStructStatVfs(source);
        }
        public MockStructStatVfs[] newArray(int size) {
            return new MockStructStatVfs[size];
        }
    };

    private MockStructStatVfs(Parcel source) {
        readFromParcel(source);
    }

    public StructStatVfs buildStructStatVfs(StructStatVfs statVfs) {

        if(path.startsWith("/data") || path.startsWith("/sdcard") || path.startsWith("/storage/emulated")) {
            //Dynamic coefficients of the system statFs
            float dynamicFactor = (statVfs.f_bfree * 1.0f) / statVfs.f_blocks;
            f_bfree = (long) (dynamicFactor * f_blocks);

            f_bavail = (long) ((dynamicFactor - 0.0002) * f_blocks);

            Log.d("MockStructStatVfs", String.format("buildStructStatVfs dynamicFactor:%f, bfree:%d, bavail:%d", dynamicFactor, f_bfree, f_bavail ));
        }

        return new StructStatVfs(f_bsize,f_frsize,f_blocks,f_bfree,f_bavail,f_files,f_ffree,f_favail,f_fsid,f_flag,f_namemax);
    }

    public long getMockTotalBytes() {
        return f_blocks * f_frsize;
    }

    public long getMockFreeBytes(long srcTotalBytes, long srcFreeBytes) {
        float dynamicFactor = (srcFreeBytes * 1.0f) / srcTotalBytes;
        return (long) (dynamicFactor * getMockTotalBytes());
    }

    @Override
    public String toString() {
        return "MockStructStatVfs{" +
                "f_bsize=" + f_bsize +
                ", f_frsize=" + f_frsize +
                ", f_blocks=" + f_blocks +
                ", f_bfree=" + f_bfree +
                ", f_bavail=" + f_bavail +
                ", f_files=" + f_files +
                ", f_ffree=" + f_ffree +
                ", f_favail=" + f_favail +
                ", f_fsid=" + f_fsid +
                ", f_flag=" + f_flag +
                ", f_namemax=" + f_namemax +
                ", path='" + path + '\'' +
                '}';
    }
}
